package com.minis.beans.factory.annotation;

import com.minis.aop.ProxyFactoryBean;
import com.minis.beans.factory.config.BeanPostProcessor;
import com.minis.beans.exception.BeansException;
import com.minis.beans.factory.support.AbstractAutowireCapableBeanFactory;
import com.minis.beans.factory.support.BeanFactory;

import java.lang.reflect.Field;

/**
 * 解析 Autowired 注解的处理器
 */
public class AutowiredAnnotationBeanPostProcessor implements BeanPostProcessor {
    private AbstractAutowireCapableBeanFactory beanFactory;

    public AbstractAutowireCapableBeanFactory getBeanFactory() {
        return beanFactory;
    }

    public void setBeanFactory(AbstractAutowireCapableBeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Object result = bean;
        System.out.println("后处理器————————————处理的 bean: " + result);

        Class<?> clazz = bean.getClass();
        Field[] fields = clazz.getDeclaredFields();
        if (fields != null) {
            for (Field field : fields) {
                boolean isAutowired = field.isAnnotationPresent(Autowired.class);
                if (isAutowired) {
                    String fieldName = field.getName();
                    System.out.println("解析 Autowired 注解, fieldName：" + fieldName);

                    // 处理 ProxyFactoryBean 中的 beanFactory
                    if ("beanFactory".equals(fieldName)) {
                        // 设置属性值
                        field.setAccessible(true);
                        try {
                            field.set(bean, this.getBeanFactory());
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                        continue;
                    }

                    // fieldName 需要对应上 bean 的名字
                    Object autowiredObj = this.getBeanFactory().getBean(fieldName);
                    // 设置属性值
                    field.setAccessible(true);
                    try {
                        field.set(bean, autowiredObj);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return result;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }
}
